import datetime
import hashlib
import time
import uuid

import captcha as captcha
import re
import json

from django.core.cache import cache
from django.core.handlers.wsgi import WSGIRequest
from django.core.mail import send_mail
from django.template import loader
from django.views.decorators.csrf import csrf_exempt
from rest_framework.views import APIView

from UserProfile import models
from django.contrib.auth.hashers import make_password, check_password
from django.http import HttpResponse, JsonResponse

# 验证码需要导入的模块
from captcha.models import CaptchaStore
from captcha.helpers import captcha_image_url
import base64
from Blog.util import DataFailed
from rest_framework.response import Response
# Create your views here.



##获取token
from czllblog import settings


def get_token(name):
    # 生成一个md5对象
    md5 = hashlib.md5()
    # 往里添加值,必须是bytes格式
    # time.time()生成时间戳类型,转成字符串,再encode转成bytes格式
    md5.update(str(time.time()).encode('utf-8'))
    md5.update(name.encode('utf-8'))
    return md5.hexdigest()

# @csrf_exempt
# def index(request):
#     token = csrf.get_token(request)
#     return HttpResponse(json.dumps({'token': token}))
# #注册 使用rest_framework
class Register(APIView):
    #使用rest_framework用户认证，authentication_classes = []表示无需登录
    authentication_classes = []
    def post(self, request, *args, **kwargs):
        response = {'status': 200, 'msg': '注册成功'}
        username = request.POST.get('username')
        email = request.POST.get('email' ,None)
        passwd = request.POST.get('passwd' ,None)
        repasswd = request.POST.get('repasswd' ,None)
        captchaStr = request.POST.get('captcha' ,None)
        captchaHashkey = request.POST.get('captchaHashkey' ,None)
        if checkCaptcha(captchaStr,captchaHashkey)==False:
            raise DataFailed({"status": 202, "msg": "验证码错误"})
        if len(username)<6:
            raise DataFailed({"status": 203, "msg": "用户名长度不小于6"})
        matchUserName = re.match(r'^[A-Za-z0-9]+$', username)
        if  matchUserName ==None:
            raise DataFailed({"status": 203, "msg": "用户名由字母和数字组成"})
        compileemail = re.compile(r'^\w+@(\w+\.)+(com|cn|net)$')
        searchemail = compileemail.search(email)
        if searchemail==None:
            raise DataFailed({"status": 203, "msg": "邮箱格式不正确"})
        flag = 0

        resUser = models.User.objects.filter(username=username).exists()
        if resUser:
            raise DataFailed({"status": 204, "msg": "用户名已存在"})

        resemail = models.User.objects.filter(email=email).exists()
        if resemail:
            raise DataFailed({"status": 204, "msg": "邮箱已存在"})
        check = checkPass(passwd,repasswd)
        if check['code']==0:
            raise DataFailed({"status": 205, "msg": check['msg']})
        else:
            data= {'username': username, 'password': make_password(passwd, None, 'pbkdf2_sha256'),'email':email,'avatar':'default/avatar.jpg'}
            try:
                res = models.User.objects.create(**data)
            except:
                raise DataFailed({"status": 210, "msg": "注册失败"})
        return Response(response)
#登录
class Login(APIView):
    authentication_classes = []
    def post(self, request, *args, **kwargs):
        response = {'status': 200, 'msg': '登录成功'}
        username = request.POST.get('username', None)
        password = request.POST.get('passwd', None)
        captchaStr = request.POST.get('captcha', None)
        captchaHashkey = request.POST.get('captchaHashkey', None)
        if checkCaptcha(captchaStr, captchaHashkey) == False:
            raise DataFailed({"status": 202, "msg": "验证码错误"})
        else:
            try:
                res = models.User.objects.filter(username=username).values()  # 获取用户
                if check_password(password, res[0]['password']):  # 验证密码
                    token = get_token(username)
                else:
                    raise DataFailed({"status": 204, "msg": "密码或用户名错误"})

            except:
                raise DataFailed({"status": 203, "msg": "用户名不存在"})
            # 保存到数据库
            # update_or_create更新或者创建


            if request.META.get('HTTP_X_FORWARDED_FOR'):
                ip_add = request.META['HTTP_X_FORWARDED_FOR']
            else:
                ip_add = request.META['REMOTE_ADDR']
            try:
                now = datetime.datetime.now()
                models.User.objects.filter(id=res[0]['id']).update(token=token,last_login=now,last_ip_add = ip_add)
                response['token'] = token
            except:
                raise DataFailed({"status": 205, "msg": "登录失败"})
        return Response(response)


class sendEmail(APIView):
    # authentication_classes = []
    def get(self, request, *args, **kwargs):
        user = request.user
        email = user[0]['email']
        # email = 'gyzhengjy@163.com'
        response = {'status': 200, 'msg': '发送成功'}
        reciever = [
            email
        ]
        # 生成随机字符
        random_str = get_random_str()
        # 拼接验证链接（加网址）
        url = "http://47.103.4.114:8080/email_active/" + random_str

        # 加载激活模板
        tmp = loader.get_template('email/active.html')
        # 渲染
        html_str = tmp.render({'url': url})

        title = "czll博客邮箱验证"
        msg = ""
        email_from = settings.DEFAULT_FROM_EMAIL
        # 发送邮件
        try:
            send_mail(title, msg, email_from, reciever,html_message=html_str)
            # 记录 token 对应的邮箱是谁 v  k
            cache.set(random_str, email, 60*15)
        except  Exception as e:
            print(e)
            response['status'] = 201
            response['msg'] = "失败"
        return JsonResponse(response,safe=False)


# 验证验证码
def checkCaptcha(captchaStr, captchaHashkey):
    if captchaStr and captchaHashkey:
        try:
            # 获取根据hashkey获取数据库中的response值
            get_captcha = CaptchaStore.objects.get(hashkey=captchaHashkey)
            # 如果验证码匹配
            if get_captcha.response == captchaStr.lower():
                return True
            else:
                return False
        except:
            return False
    else:
        return False
#验证密码规则
def checkPass(passwd,repasswd):
    if len(passwd) <6:
        code = 0
        msg = "密码长度不小于6"
    elif passwd!=repasswd:
        code = 0
        msg = "密码不一致"
    else:
        code = 1
        msg = "验证成功"
    data  = {'code':code,'msg':msg}
    return data


# 创建验证码
def captcha():
    # 验证码，第一次请求
    hashkey = CaptchaStore.generate_key()
    image_url = captcha_image_url(hashkey)
    captcha = {'hashkey': hashkey, 'image_url': image_url}
    return captcha


def refreshCaptcha(request):
    data = captcha()
    res = {'code':200,'msg':'获取验证码成功','data':data}
    return HttpResponse(json.dumps(res), content_type='application/json')

##生成随机字段
def get_random_str():
    uuid_val = uuid.uuid4()
    uuid_str = str(uuid_val).encode("utf-8")
    md5 = hashlib.md5()
    md5.update(uuid_str)
    return md5.hexdigest()
#验证邮箱
def active(req, random_str):
    # 拿参数对应的缓存数据
    res = cache.get(random_str)
    if res:
        # 通过邮箱找到对应用户
        # 给用户的状态字段做更新，从未激活变成激活状态
        try:
            models.User.objects.filter(email=res).update(email_status=1)
        except:
            return HttpResponse(res+"激活失败，请重新激活")
        return HttpResponse(res+"激活成功")
    else:
        return HttpResponse(random_str + "验证链接无效")
